import tweepy
from optparse import OptionParser
import sys
from urllib import urlencode
import re
import locale
import json
import time
import pdb
import fileinput
import os
import threading

class NetworkMaster:
	def __init__(self, screen_name):
		self.screen_name = screen_name

		# Account 0 (Imp2Fol)
		#Authentication tokens for Twitter, authenticate, and check rate limit status
		self.auth0 = tweepy.OAuthHandler("6VgMBlOXueMbgUtTcLDZSA", "c246Cwf844ITBqf6QcmIpaFIJLInNZSZauDrvE7sWw")
		self.auth0.set_access_token("335838961-lAHD4suoXmXEEasLNtgCAfNXXKBOc3pNBV1MFiZf", "9NohmpnKwFgnmlQfaYcOg1JUr6zInoMY3wOEl0pzNXI")
		self.api0 = tweepy.API(self.auth0)
		self.my_rate_limit_status0 = self.api0.rate_limit_status()

		# Account 1 (Conv2Fol)
		# Authentication tokens for Twitter, authenticate, and check rate limit status
		self.auth1 = tweepy.OAuthHandler("uEaf4MBF9pu6ePTJT0T3w", "uTwMUJGo6dqciEJ1vVrCJ3wgHrSYR9Vysz2TJ01GLyA")
		self.auth1.set_access_token("335841614-072kBBbxiWHcezvN3Eo9VmMzFnGbehUrqWMXp0Tu", "03jqfVjGPXe219hJHNFBlkKK96igdsvyoFiitnuoJ8")
		self.api1 = tweepy.API(self.auth1)
		self.my_rate_limit_status1 = self.api1.rate_limit_status()
		
		# Account 2 (Int2Fol)
		# Authentication tokens for Twitter, authenticate, and check rate limit status
		self.auth2 = tweepy.OAuthHandler("P07XwnJHUN3dqQxG4zUpw", "fJVg6q79jdtaPNvh2tc1ipv8x9lEiTcwzRf3C24nFQ")
		self.auth2.set_access_token("335844930-HmUJwXcIYbyhvFZE0xCuOZbAIvWjR2gEGV83AxsK", "MTJ2GOv02777TreJkawARTr2YQSMb3UoEjPPCefnGPA")
		self.api2 = tweepy.API(self.auth2)
		self.my_rate_limit_status2 = self.api2.rate_limit_status()

		# Account 3 (Con2Fol)
		# Authentication tokens for Twitter, authenticate, and check rate limit status
		self.auth3 = tweepy.OAuthHandler("FGlMRu1UBRD0K2a0BYBj1w", "ra1uQ6RXpupAzDotakWchgaCrKG5nSlmcST6J5XTl6c")
		self.auth3.set_access_token("335853926-wUuKeH3I4z46LlTVIZ06vyAt3NXSRuINQJj3sYuJ", "qW93vOnz7E7Tq1pMItsEt8bPt2oH04A2WukDP3FplU")
		self.api3 = tweepy.API(self.auth3)
		self.my_rate_limit_status3 = self.api3.rate_limit_status()
		
		self.account_number = 1
		self.expander_service = 1
		
		# Initialize Twitter (multiple accounts) and Backtype API calls
		self.api_calls = {0:0, 1:0, 2:0, 3:0}
		self.number_exceptions = {0:0, 1:0, 2:0}
		
		self.Process(self.screen_name)
		
	def CFN(self, outputfile, screen_name):
		os.system("python /Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/scripts/CFN.py %s" %outputfile + " %s" %screen_name)	
		
	def IFN(self, outputfile, screen_name):
		os.system("python /Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/scripts/IFN.py %s" %outputfile + " %s" %screen_name)				

	def IFN2PFN(self, inputfile, outputfile, screen_name):
		os.system("python /Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/scripts/IFN2PFN.py %s" %inputfile + " %s"%outputfile + " %s" %screen_name)				

	def PFN(self, inputfile, outputfile, screen_name):
		os.system("python /Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/scripts/PFN.py %s" %inputfile + " %s" %outputfile + " %s" %screen_name)				
				
	def RFN(self, inputfile, outputfile, screen_name):
			os.system("python /Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/scripts/RFN.py %s" %inputfile + " %s" %outputfile + " %s" %screen_name)
					
	def GetUserID(self, screen_name):		
		# Keep track of the Twitter API Calls
		self.api_calls[self.account_number] = self.api_calls[self.account_number] + 1
		print "Api calls for account %s :" %self.account_number + " [%s] " %self.api_calls[self.account_number] + " (from GetUserTimeline)"
		if (self.api_calls[self.account_number] > 325):

			# Get the state of all API keys
			self.api_calls[0] = 350 - self.api0.rate_limit_status()["remaining_hits"]
			self.api_calls[1] = 350 - self.api1.rate_limit_status()["remaining_hits"]
			self.api_calls[2] = 350 - self.api2.rate_limit_status()["remaining_hits"]
			self.api_calls[3] = 350- self.api3.rate_limit_status()["remaining_hits"]

			# Ensure from the start that we are using the right API key according to the rate limits.
			while (self.api_calls[self.account_number] > 325):
				self.account_number = (self.account_number + 1) % 4 # Modulo, so that account numbers rotate
				print "Sleeping for 10 minutes while API refreshes ..."
				self.output_logs.write("Sleeping for 10 minutes while API refreshes... \n")
				time.sleep(10*60)

		user_id = None

		try:
			if (self.account_number == 0):
				user_id = self.api0.get_user(screen_name).id
			elif (self.account_number == 1):
				user_id = self.api1.get_user(screen_name).id
			elif (self.account_number == 2): 
				user_id = self.api2.get_user(screen_name).id
			elif (self.account_number == 3):
				user_id = self.api3.get_user(screen_name).id
		except:
			self.output_logs.write("Problem getting user id for user %s" %screen_name  + "Error: Not Authorized \n")
			print "Problem getting user id for user %s:" %screen_name + "Error: Not Authorized"
			pass

		return user_id
					
	def Process(self, screen_name):	
		
		user_id = self.GetUserID(self.screen_name)		
		
		next = True
		
		while(next):
						
			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")	
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)

			#######	
			# CFN #
			#######
			CFN_done = False
			outputfile_cfn = "%s" %output_dir + "/CF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"
			
			while not(CFN_done):
			
				self.CFN(outputfile_cfn, self.screen_name)
				
				if not(os.path.getsize(outputfile_cfn) == 0):
					CFN_done = True

			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)
			
			#######
			# IFN #
			#######
			IFN_done = False
			outputfile_ifn = "%s" %output_dir + "/IF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"
			outputfile_ifn_f = "%s" %output_dir + "/IF-%s" %start_time + "-%s" %time.strftime("%H""%M") + "_filtered.out"
			
			while not(IFN_done):
				
				self.IFN(outputfile_ifn, self.screen_name)
					
				if not(os.path.getsize(outputfile_ifn) == 0):
					IFN_done = True
					
			# Check start time and output directory in case the date changed.				
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)
			
			###########
			# IFN2PFN #
			###########	
					
			inputfile_ifn2pfn = outputfile_ifn
			outputfile_ifn2pfn = "%s" %output_dir + "/IF2PF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"
			self.IFN2PFN(outputfile_ifn, outputfile_ifn2pfn, self.screen_name)
						
			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)
			
			#######			
			# PFN #
			#######
			
			inputfile_pfn = outputfile_ifn2pfn
			fqn_filename = inputfile_pfn.split('.')
			
			PFN_done = False
			inputfile_pfn = fqn_filename[0] + ".predicted"
			outputfile_pfn = "%s" %output_dir + "/PF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"
			
			while not(PFN_done):
			
				self.PFN(inputfile_pfn, outputfile_pfn, self.screen_name) 
				
				if not(os.path.getsize(outputfile_pfn) == 0):
					PFN_done = True
				
			end_time = time.strftime("%Y%m%d")
			
			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name	
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)

			###########
			# IFN2RFN #
			###########	
			
			start_time = time.strftime("%Y%m%d")
			inputfile_ifn2rfn = outputfile_ifn2pfn
			outputfile_ifn2rfn = "%s" %output_dir + "/IF2RF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"
			outputfile_ibr = "%s" %output_dir + "/IF2RF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".recommended"
			
			# Run the UserBasedEvaluator java program and create the output locally
			os.system("ssh ocastaneda@145.94.40.203 'source /Users/ocastaneda/.bash_profile ; java ItemBasedRecommender %s" %inputfile_ifn2rfn + " %s'" %user_id + " > %s" %outputfile_ifn2rfn)
			
			time.sleep(5*60)
			
			#output_processed = open(outputfile_ifn2rfn, 'r')
			#output_recommended = open(outputfile_ibr, 'w')

			#for line in output_processed:
			#	pattern = re.compile(r'RecommendedItem\[item:(\d+), value:1\.0]', re.UNICODE)
			#	recommended_user = pattern.findall(line)
			#	output_recommended.append("%s" %user_id + ",%s" %recommended_user + "\n")
			#output_processed.close()
			#output_recommended.close()			
			
			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name	
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)
				
			#######		
			# RFN #
			#######
			
			inputfile_rfn = outputfile_ifn2rfn
			fqn_filename = inputfile_rfn.split('.')
			
			RFN_done = False
			inputfile_rfn = fqn_filename[0] + ".recommended"
			outputfile_rfn = "%s" %output_dir + "/RF-%s" %start_time + "-%s" %time.strftime("%H""%M") + ".out"

			while not(RFN_done):

				self.RFN(inputfile_rfn, outputfile_rfn, self.screen_name) 

				if not(os.path.getsize(outputfile_rfn) == 0):
					RFN_done = True

			end_time = time.strftime("%Y%m%d")
			
			# Check start time and output directory in case the date changed.
			start_time = time.strftime("%Y%m%d")
			output_dir = "/Users/ocastaneda/Documents/TU_Delft/2010/IN5000/Tools/TweetPredict/output/output-%s" %start_time +"-%s" %self.screen_name	
			
			# Make an output directory for all of the days output
			if not(os.path.exists(output_dir)):
				os.system("mkdir %s" %output_dir)

####################################################################################

def RunMain():
	usage = "(First version) usage: %prog <screen_name>"
	parser = OptionParser(usage)
	(options, args) = parser.parse_args()

	if( len(args) < 1):
		print "Invalid number of arguments. Use NM.py --help to see the details."
	else:
		screen_name = args[0]

		try:
			print "Network Master: orchestrating the running of all scripts ..."

			NetworkMaster(screen_name)
		except:
			pass
			raise

if( __name__ == "__main__"):
	RunMain()
